// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DataGridViewBlinkingTextBoxCell.cs" company="Open Trader">
//   Copyright (c) David Denis (david.denis@systemathics.com)
// </copyright>
// <summary>
//   |  Open Trader - The Open Source Systematic Trading Platform
//   |
//   |  This program is free software: you can redistribute it and/or modify
//   |  it under the terms of the GNU General Public License as published by
//   |  the Free Software Foundation, either version 2 of the License, or
//   |  (at your option) any later version.
//   |
//   |  This program is distributed in the hope that it will be useful,
//   |  but WITHOUT ANY WARRANTY; without even the implied warranty of
//   |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   |  GNU General Public License for more details.
//   |
//   |  You should have received a copy of the GNU General Public License
//   |  along with this program.  If not, see http://www.gnu.org/licenses
//   |
//   |  Up to date informations about Open Trader can be found at :
//   |    http://opentrader.org
//   |    http://opentrader.codeplex.com
//   |
//   |  For professional services, please visit us at :
//   |    http://www.systemathics.com
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Org.OpenTrader.Framework.UI.Forms
{
    #region Using Directives

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Windows.Forms.VisualStyles;

    #endregion

    /// <summary>
    /// The data grid view blinking text box cell.
    /// </summary>
    public class DataGridViewBlinkingTextBoxCell : DataGridViewTextBoxCell
    {
        #region Constants and Fields

        /// <summary>
        /// The blink style.
        /// </summary>
        public static readonly DataGridViewCellStyle BlinkStyle;

        /// <summary>
        /// The normal style.
        /// </summary>
        public static readonly DataGridViewCellStyle NormalStyle;

        /// <summary>
        /// The next repaint style.
        /// </summary>
        private DataGridViewCellStyle nextRepaintStyle = NormalStyle;

        /// <summary>
        /// The previousB.
        /// </summary>
        private bool previousB;

        /// <summary>
        /// The value.
        /// </summary>
        private object value;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes static members of the <see cref="DataGridViewBlinkingTextBoxCell"/> class.
        /// </summary>
        static DataGridViewBlinkingTextBoxCell()
        {
            NormalStyle = new DataGridViewCellStyle();
            NormalStyle.BackColor = UIDefaults.GridCellBackground;
            NormalStyle.ForeColor = UIDefaults.GridCellForeground;
            NormalStyle.Font = UIDefaults.GridCellFont;

            BlinkStyle = new DataGridViewCellStyle();
            BlinkStyle.BackColor = UIDefaults.GridCellBlinkBackground;
            BlinkStyle.ForeColor = UIDefaults.GridCellForeground;
            BlinkStyle.Font = UIDefaults.GridCellFont;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DataGridViewBlinkingTextBoxCell"/> class.
        /// </summary>
        public DataGridViewBlinkingTextBoxCell()
        {
            this.value = string.Empty;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets Value.
        /// </summary>
        public new object Value
        {
            get
            {
                return this.value;
            }

            set
            {
                if (value == null)
                {
                    value = string.Empty;
                }

                var previous = this.value;
                this.value = value;

                // Stdout.WriteLine("From " + previous + " to " + value);
                // Value has changed, set to "please blink"
                if (!previous.Equals(this.value))
                {
                    this.Blink(true);
                }
                else
                {
                    this.Blink(false); // Value didn't change, set to "please unblink if necessary"
                }
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// The blink.
        /// </summary>
        /// <param name="b">
        /// The b.
        /// </param>
        public void Blink(bool b)
        {
            // The state changing from off to on or on to off (this need a repaint)
            if (b != this.previousB)
            {
                if (b)
                {
                    // Stdout.WriteLine(string.Format("{0} Blink   {1};{2}",PrettyPrinter.Timings.Format(Timings.Now), RowIndex, ColumnIndex));
                    this.nextRepaintStyle = BlinkStyle;
                }
                else
                {
                    // Stdout.WriteLine(string.Format("{0} UnBlink {1};{2}", PrettyPrinter.Timings.Format(Timings.Now), RowIndex, ColumnIndex));
                    this.nextRepaintStyle = NormalStyle;
                }

                this.DataGridView.InvalidateCell(this);
            }

            // store previous
            this.previousB = b;
        }

        #endregion

        #region Methods

        /// <summary>
        /// The paint.
        /// </summary>
        /// <param name="graphics">
        /// The graphics.
        /// </param>
        /// <param name="clipBounds">
        /// The clip bounds.
        /// </param>
        /// <param name="cellBounds">
        /// The cell bounds.
        /// </param>
        /// <param name="rowIndex">
        /// The row index.
        /// </param>
        /// <param name="cellState">
        /// The cell state.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <param name="formattedValue">
        /// The formatted value.
        /// </param>
        /// <param name="errorText">
        /// The error text.
        /// </param>
        /// <param name="cellStyle">
        /// The cell style.
        /// </param>
        /// <param name="advancedBorderStyle">
        /// The advanced border style.
        /// </param>
        /// <param name="paintParts">
        /// The paint parts.
        /// </param>
        protected override void Paint(
            Graphics graphics, 
            Rectangle clipBounds, 
            Rectangle cellBounds, 
            int rowIndex, 
            DataGridViewElementStates cellState, 
            object value, 
            object formattedValue, 
            string errorText, 
            DataGridViewCellStyle cellStyle, 
            DataGridViewAdvancedBorderStyle advancedBorderStyle, 
            DataGridViewPaintParts paintParts)
        {
            base.Paint(
                graphics, 
                clipBounds, 
                cellBounds, 
                rowIndex, 
                cellState, 
                value, 
                formattedValue, 
                errorText, 
                this.nextRepaintStyle, 
                advancedBorderStyle, 
                paintParts);
        }

        #endregion
    }
}